import { Request, Response, NextFunction } from 'express';
import * as bcrypt from 'bcryptjs';
import { prisma } from '../../config/database';
import { logger } from '../../utils/logger';
import { ConfigUtils } from '../../config';
import { BaseController } from '../../utils/autoBind';
import { ResponseUtils } from '../../utils/responseUtils';
import { 
  BUSINESS_ERROR_CODES, 
  VALIDATION_ERROR_CODES,
  COMMON_ERROR_CODES
} from '../../utils/errorCodes';
import { getFileUrl, deleteFile } from '../../middleware/upload';


export class UserController extends BaseController {
  // 获取用户列表
  async getUsers(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { page = 1, limit = 20, search = '', status, roleId } = req.query;
      const pageNum = parseInt(page as string);
      const limitNum = parseInt(limit as string);
      const skip = (pageNum - 1) * limitNum;

      // 构建查询条件
      const where: any = {};
      
      if (search) {
        where.OR = [
          { username: { contains: search as string } },
          { email: { contains: search as string } },
          { realName: { contains: search as string } },
          { phone: { contains: search as string } }
        ];
      }

      if (status) {
        where.status = status;
      }

      if (roleId) {
        where.userRoles = {
          some: {
            roleId: parseInt(roleId as string)
          }
        };
      }

      // 查询用户列表
      const [users, total] = await Promise.all([
        prisma.user.findMany({
          where,
          select: {
            id: true,
            username: true,
            email: true,
            realName: true,
            avatar: true,
            phone: true,
            status: true,
            lastLoginAt: true,
            createdAt: true,
            updatedAt: true,
            userRoles: {
              include: {
                role: {
                  select: {
                    id: true,
                    name: true,
                    description: true
                  }
                }
              }
            }
          },
          skip,
          take: limitNum,
          orderBy: { createdAt: 'desc' }
        }),
        prisma.user.count({ where })
      ]);

      ResponseUtils.paginated(res, users, total, pageNum, limitNum, '获取用户列表成功');
    } catch (error) {
      next(error);
    }
  }

  // 根据ID获取用户
  async getUserById(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const userId = parseInt(id);

      if (isNaN(userId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '用户ID必须是数字');
        return;
      }

      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: {
          id: true,
          username: true,
          email: true,
          realName: true,
          avatar: true,
          phone: true,
          status: true,
          lastLoginAt: true,
          createdAt: true,
          updatedAt: true,
          userRoles: {
            include: {
              role: {
                select: {
                  id: true,
                  name: true,
                  description: true
                }
              }
            }
          }
        }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      ResponseUtils.success(res, user, '获取用户信息成功');
    } catch (error) {
      next(error);
    }
  }

  // 创建用户
  async createUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { username, email, password, realName, phone, roleIds } = req.body;

      // 检查用户名和邮箱是否已存在
      const existingUser = await prisma.user.findFirst({
        where: {
          OR: [
            { username },
            { email }
          ]
        }
      });

      if (existingUser) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_ALREADY_EXISTS, '用户名或邮箱已存在');
        return;
      }

      // 加密密码
      const saltRounds = ConfigUtils.getBcryptRounds();
      const hashedPassword = await bcrypt.hash(password, saltRounds);

      // 创建用户
      const userData: any = {
        username,
        email,
        password: hashedPassword,
        realName,
        phone
      };

      if (roleIds) {
        userData.userRoles = {
          create: roleIds.map((roleId: number) => ({
            roleId
          }))
        };
      }

      const user = await prisma.user.create({
        data: userData,
        select: {
          id: true,
          username: true,
          email: true,
          realName: true,
          avatar: true,
          phone: true,
          status: true,
          createdAt: true,
          userRoles: {
            include: {
              role: {
                select: {
                  id: true,
                  name: true,
                  description: true
                }
              }
            }
          }
        }
      });

      // 记录操作日志
      logger.info(`用户创建成功: ${user.username} (ID: ${user.id})`);

      ResponseUtils.created(res, user, '用户创建成功');
    } catch (error) {
      next(error);
    }
  }

  // 更新用户
  async updateUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const userId = parseInt(id);
      const { username, email, realName, phone, roleIds } = req.body;

      if (isNaN(userId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '用户ID必须是数字');
        return;
      }

      // 检查用户是否存在
      const existingUser = await prisma.user.findUnique({
        where: { id: userId }
      });

      if (!existingUser) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 检查用户名和邮箱是否被其他用户使用
      if (username || email) {
        const duplicateUser = await prisma.user.findFirst({
          where: {
            OR: [
              username ? { username } : {},
              email ? { email } : {}
            ],
            NOT: { id: userId }
          }
        });

        if (duplicateUser) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_ALREADY_EXISTS, '用户名或邮箱已被其他用户使用');
          return;
        }
      }

      // 更新用户信息
      const updateData: any = {
        username,
        email,
        realName,
        phone
      };

      if (roleIds) {
        updateData.userRoles = {
          deleteMany: {},
          create: roleIds.map((roleId: number) => ({
            roleId
          }))
        };
      }

      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: updateData,
        select: {
          id: true,
          username: true,
          email: true,
          realName: true,
          avatar: true,
          phone: true,
          status: true,
          updatedAt: true,
          userRoles: {
            include: {
              role: {
                select: {
                  id: true,
                  name: true,
                  description: true
                }
              }
            }
          }
        }
      });

      // 记录操作日志
      logger.info(`用户更新成功: ${updatedUser.username} (ID: ${updatedUser.id})`);

      ResponseUtils.updated(res, updatedUser, '用户更新成功');
    } catch (error) {
      next(error);
    }
  }

  // 删除用户
  async deleteUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const userId = parseInt(id);

      if (isNaN(userId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '用户ID必须是数字');
        return;
      }

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { username: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 删除用户（级联删除用户角色关联）
      await prisma.user.delete({
        where: { id: userId }
      });

      // 记录操作日志
      logger.info(`用户删除成功: ${user.username} (ID: ${userId})`);

      ResponseUtils.deleted(res, '用户删除成功');
    } catch (error) {
      next(error);
    }
  }

  // 重置密码
  async resetPassword(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { newPassword } = req.body;
      const userId = parseInt(id);

      if (isNaN(userId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '用户ID必须是数字');
        return;
      }

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { username: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 加密新密码
      const saltRounds = ConfigUtils.getBcryptRounds();
      const hashedPassword = await bcrypt.hash(newPassword, saltRounds);

      // 更新密码
      await prisma.user.update({
        where: { id: userId },
        data: { password: hashedPassword }
      });

      // 记录操作日志
      logger.info(`用户密码重置成功: ${user.username} (ID: ${userId})`);

      ResponseUtils.success(res, null, '密码重置成功');
    } catch (error) {
      next(error);
    }
  }

  // 更新用户状态
  async updateUserStatus(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { status } = req.body;
      const userId = parseInt(id);

      if (isNaN(userId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '用户ID必须是数字');
        return;
      }

      // 验证状态值
      const validStatuses = ['ACTIVE', 'INACTIVE', 'BANNED'];
      if (!validStatuses.includes(status)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_VALUE_ERROR, '无效的用户状态');
        return;
      }

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { username: true, status: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 更新用户状态
      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: { status },
        select: {
          id: true,
          username: true,
          status: true,
          updatedAt: true
        }
      });

      // 记录操作日志
      logger.info(`用户状态更新成功: ${user.username} (ID: ${userId}) - ${user.status} -> ${status}`);

      ResponseUtils.updated(res, updatedUser, '用户状态更新成功');
    } catch (error) {
      next(error);
    }
  }

  // 启用用户
  async enableUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const userId = parseInt(id);

      if (isNaN(userId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '用户ID必须是数字');
        return;
      }

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { username: true, status: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      if (user.status === 'ACTIVE') {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_ALREADY_ACTIVE, '用户已经是启用状态');
        return;
      }

      // 启用用户
      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: { status: 'ACTIVE' },
        select: {
          id: true,
          username: true,
          status: true,
          updatedAt: true
        }
      });

      // 记录操作日志
      logger.info(`用户启用成功: ${user.username} (ID: ${userId})`);

      ResponseUtils.updated(res, updatedUser, '用户启用成功');
    } catch (error) {
      next(error);
    }
  }

  // 禁用用户
  async disableUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const userId = parseInt(id);

      if (isNaN(userId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '用户ID必须是数字');
        return;
      }

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { username: true, status: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      if (user.status === 'INACTIVE') {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_ALREADY_INACTIVE, '用户已经是禁用状态');
        return;
      }

      // 禁用用户
      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: { status: 'INACTIVE' },
        select: {
          id: true,
          username: true,
          status: true,
          updatedAt: true
        }
      });

      // 记录操作日志
      logger.info(`用户禁用成功: ${user.username} (ID: ${userId})`);

      ResponseUtils.updated(res, updatedUser, '用户禁用成功');
    } catch (error) {
      next(error);
    }
  }

  // 获取用户统计信息
  async getUserStats(_req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const [
        totalUsers,
        activeUsers,
        inactiveUsers,
        bannedUsers,
        todayNewUsers,
        thisWeekNewUsers,
        thisMonthNewUsers
      ] = await Promise.all([
        prisma.user.count(),
        prisma.user.count({ where: { status: 'ACTIVE' } }),
        prisma.user.count({ where: { status: 'INACTIVE' } }),
        prisma.user.count({ where: { status: 'BANNED' } }),
        prisma.user.count({
          where: {
            createdAt: {
              gte: new Date(new Date().setHours(0, 0, 0, 0))
            }
          }
        }),
        prisma.user.count({
          where: {
            createdAt: {
              gte: new Date(new Date().setDate(new Date().getDate() - 7))
            }
          }
        }),
        prisma.user.count({
          where: {
            createdAt: {
              gte: new Date(new Date().getFullYear(), new Date().getMonth(), 1)
            }
          }
        })
      ]);

      const stats = {
        total: totalUsers,
        active: activeUsers,
        inactive: inactiveUsers,
        banned: bannedUsers,
        todayNew: todayNewUsers,
        thisWeekNew: thisWeekNewUsers,
        thisMonthNew: thisMonthNewUsers
      };

      ResponseUtils.success(res, stats, '获取用户统计信息成功');
    } catch (error) {
      next(error);
    }
  }

  // 上传头像
  async uploadAvatar(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      if (!req.file) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.REQUIRED_FIELD_MISSING, '请选择要上传的头像文件');
        return;
      }

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { id: true, username: true, avatar: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 删除旧头像文件
      if (user.avatar) {
        const oldAvatarPath = user.avatar.split('/').pop();
        if (oldAvatarPath) {
          deleteFile(oldAvatarPath);
        }
      }

      // 生成新的头像URL
      const avatarUrl = getFileUrl(req.file.filename);

      // 更新用户头像
      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: { avatar: avatarUrl },
        select: {
          id: true,
          username: true,
          avatar: true,
          updatedAt: true
        }
      });

      logger.info(`用户头像上传成功: ${user.username} (ID: ${userId})`);

      ResponseUtils.updated(res, updatedUser, '头像上传成功');
    } catch (error) {
      next(error);
    }
  }

  // 更新个人资料
  async updateProfile(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      const { realName, email, phone } = req.body;

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { id: true, username: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 检查邮箱是否已被其他用户使用
      if (email) {
        const existingUser = await prisma.user.findFirst({
          where: {
            email,
            id: { not: userId }
          }
        });

        if (existingUser) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_ALREADY_EXISTS, '该邮箱已被其他用户使用');
          return;
        }
      }

      // 更新用户资料
      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: {
          realName: realName || undefined,
          email: email || undefined,
          phone: phone || undefined
        },
        select: {
          id: true,
          username: true,
          realName: true,
          email: true,
          phone: true,
          avatar: true,
          updatedAt: true
        }
      });

      logger.info(`用户资料更新成功: ${user.username} (ID: ${userId})`);

      ResponseUtils.updated(res, updatedUser, '个人资料更新成功');
    } catch (error) {
      next(error);
    }
  }

  // 获取个人资料
  async getProfile(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      // 获取用户信息
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: {
          id: true,
          username: true,
          realName: true,
          email: true,
          phone: true,
          avatar: true,
          status: true,
          lastLoginAt: true,
          createdAt: true,
          updatedAt: true,
          userRoles: {
            include: {
              role: {
                select: {
                  id: true,
                  name: true,
                  description: true
                }
              }
            }
          }
        }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      ResponseUtils.success(res, user, '获取个人资料成功');
    } catch (error) {
      next(error);
    }
  }

  // 修改密码
  async changePassword(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      const { currentPassword, newPassword } = req.body;

      // 检查用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { id: true, username: true, password: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 验证当前密码
      const isPasswordValid = await bcrypt.compare(currentPassword, user.password);
      if (!isPasswordValid) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_VALUE_ERROR, '当前密码错误');
        return;
      }

      // 加密新密码
      const saltRounds = 12;
      const hashedPassword = await bcrypt.hash(newPassword, saltRounds);

      // 更新密码
      await prisma.user.update({
        where: { id: userId },
        data: { password: hashedPassword }
      });

      logger.info(`用户密码修改成功: ${user.username} (ID: ${userId})`);

      ResponseUtils.success(res, null, '密码修改成功');
    } catch (error) {
      next(error);
    }
  }

  // 管理员为指定用户上传头像
  async uploadUserAvatar(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const targetUserId = parseInt(req.params.id);
      
      if (isNaN(targetUserId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_VALUE_ERROR, '用户ID必须是数字');
        return;
      }

      if (!req.file) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.REQUIRED_FIELD_MISSING, '请选择要上传的头像文件');
        return;
      }

      // 检查目标用户是否存在
      const targetUser = await prisma.user.findUnique({
        where: { id: targetUserId },
        select: { id: true, username: true, avatar: true }
      });

      if (!targetUser) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '目标用户不存在');
        return;
      }

      // 删除旧头像文件
      if (targetUser.avatar) {
        const oldAvatarPath = targetUser.avatar.split('/').pop();
        if (oldAvatarPath) {
          deleteFile(oldAvatarPath);
        }
      }

      // 生成新的头像URL
      const avatarUrl = getFileUrl(req.file.filename);

      // 更新用户头像
      const updatedUser = await prisma.user.update({
        where: { id: targetUserId },
        data: { avatar: avatarUrl },
        select: {
          id: true,
          username: true,
          avatar: true,
          updatedAt: true
        }
      });

      logger.info(`管理员为用户上传头像成功: ${targetUser.username} (ID: ${targetUserId})`);

      ResponseUtils.updated(res, updatedUser, '用户头像上传成功');
    } catch (error) {
      next(error);
    }
  }
}
